#ifndef PLY_H
#define PLY_H
#include <QString>
#include <QFile>
#include "lzo.h"

namespace modelspace
{
    struct wctop
    {
        char flag[4];           //文件标识  WLD
        int none;               //未知，文件里边的为0
        int none2;              //未知，文件里边为2
        char none3[8];          //未知，里面都是空白
        int none4;              //未知，0x 00 02 00 00
        int none5;              //比文件长度多216的值
        char none6[120];        //未知，空白，可能可以插入一些说明内容
        int olen;               //后边数据解压后长度                  如果是零的话大概是没有压缩吧
        int clen;               //后边的数据压缩长度      数据从156个字节后开始
    };
    struct plytop
    {
        int datalen;            //文件长度
        float none1;
        float none2;
        float none3;
        float none4;
        float none5;
        float none6;
        float none7;
        float none8;
        float none9;
        float none10;
        float none11;
        float none12;
        float none13;
        int num;                //后接每28字节一段的数据的个数,可能是对象段
    };
    struct mpoint
    {
        float x;
        float y;
        float z;
        int none1;              //00 00 00 00
        float none2;            //可能是贴图坐标u
        float none3;            //可能是贴图坐标v
        float none4;            //可能是贴图坐标n
        float U;                //可能是贴图缩放
        float V;                //可能是贴图缩放
        float none5;            //可能时贴图坐标的正反，一般为  FF FF FF FF 或 FF FF FF 00
    };
    struct plyobject            //在ply文件开头，未知的东西28个字节段
    {
        short none;             //大概是对象的效果
        short none1;            //大概是效果2
        int pointnum;           //对象的顶点数
        int pbegin;             //顶点开始索引
        int pend;               //顶点结束索引
        int facenum;            //对象的面数
        int facebegin;          //面开始索引
        int faceend;            //面结束索引
    };
    struct face
    {
        short index1;
        short index2;
        short index3;
    };
    struct wenli{
        int facecnt;            //该纹理贴图文件中所包含的三角形面贴图数, 使用时要除3
        int facestart;          //从第几个三角形面开始使用该文件的贴图, 使用时要除3
        int faceend;            //facecnt+facestart
        short facehastex;       //1:表示没有纹理，0:表示有纹理
        short none;
        int texnum;
        char name[32];
    };
    class Matrix_4_4{           //变换矩阵
    public:
        Matrix_4_4();
        Matrix_4_4(float *p);
        void read(float *p);
        float value[4][4];
    };
    class ObjMatrix{
    public:
        ObjMatrix(int objNum, int frameNum,float *pMatrix);
        Matrix_4_4 *getMatrix(int frameIndex,int objIndex);   //获得对应帧内对象的的变换矩阵
        mpoint * getFramePPoint(int frameIndex);                //获得该帧的点列表
        int calculateFrame(mpoint *p, int pointNum,plyobject *pobj);                     //计算各个帧的点列表
        ~ObjMatrix();
    protected:
        Matrix_4_4 *frame;
        int objNum;
        int frameNum;
        mpoint **point;
    };
}

class ply
{
public:
    ply();
    ply(QString filename);
    ~ply();
    int read(QString filename);
    int save(QString filename);
    bool fplyopen;
    int getpointnum(){return pointnum;}
    int getfacenum(){return facenum;}
    int getwenlinum(){return wenlinum;}
    int getFrameNum(){return frameNum;}

    modelspace::mpoint *getpointhead(){return pp;}    //点列表指针
    modelspace::mpoint *getpoint(int frameIndex){
        return this->objMatrix->getFramePPoint(frameIndex);
    }    //变换后的点列表指针
    modelspace::plytop *getplytop(){return ptop;}    //头指针
    modelspace::face *getpface(){return face;}       //面指针
    modelspace::wenli *getpwenli(){return pwenli;}    //纹理指针
    //int *getpWeiliIndex(){return (int *)pWeiliIndex;}                      //返回纹理索引指针
    int getTexIndex(int faceidx);                           //获得面对应的纹理号,和getpWeiliIndex功能一样，但上面的实现是错误的
    modelspace::plyobject *pobject;
    void static compress(QString filename);
    void static decompress(QString filename);

protected:
    long olen,clen;          //原始长度，压缩长度
    char *cdata,*odata;    //压缩数据，原始数据
    modelspace::mpoint *pp;
    modelspace::plytop *ptop;
    modelspace::face *face;
    modelspace::wenli *pwenli;
    char *pWeiliIndex;                 //纹理索引指针，纹理索引数量等于面数量
    //modelspace::Matrix_4_4 *matrix;   //变换矩阵指针
    modelspace::ObjMatrix *objMatrix;    //对象的变换矩阵指针
    int matrixNum;                    //变换矩阵
    int facenum;
    int pointnum;
    int wenlinum;
    int frameNum;                     //帧数
    int objNum;
};

class wld
{
public:
protected:
};

#endif // PLY_H
